home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / jaq / dist / dev.c.sprite < prev    next >
Encoding:
Text File  |  1992-10-26  |  15.4 KB  |  729 lines

  1. /* 
  2.  * dev.c--
  3.  *
  4.  *    Device-dependent manipulations for Sprite Exabyte
  5.  *
  6.  * Copyright 1991 Regents of the University of California
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  *
  15.  * Quote:
  16.  *      "What a depressingly stupid machine"
  17.  *      -- Marvin in _A Hitchiker's Guide to the Galaxy_
  18.  */
  19.  
  20. #ifndef lint
  21. static char rcsid[] = "$Header: /sprite/lib/forms/RCS/dev.c,v 1.0 91/01/07 18:02:37 mottsmth Exp $ SPRITE (Berkeley)";
  22. #endif /* not lint */
  23.  
  24. #include <stdio.h>
  25. #include <sprite.h>
  26. #include <dev/tape.h>
  27. #include <dev/robot.h>
  28. #include <sys/file.h>
  29. #include <fs.h>
  30. #include <status.h>
  31. #include "jaquith.h"
  32.  
  33. static char printBuf[T_MAXSTRINGLEN];
  34. extern int syserr;
  35.  
  36. #define EXB120_MAXBIN 115
  37.  
  38.  
  39. /*
  40.  *----------------------------------------------------------------------
  41.  *
  42.  * Dev_MoveVolume --
  43.  *
  44.  *    Move a volume from source slot to destination slot in jukebox
  45.  *
  46.  * Results:
  47.  *    Ptr to block of specified size or NULL;
  48.  *
  49.  * Side effects:
  50.  *    Moves robot arm. May also affect volume reader.
  51.  *
  52.  * Note:
  53.  *      The tape reader devices in the EXB-120 jukebox are given slot
  54.  *      numbers 116-119. If one of these is the destination address
  55.  *      a tape load is effectively done.  
  56.  *
  57.  *----------------------------------------------------------------------
  58.  */
  59.  
  60. int
  61. Dev_MoveVolume(robotStream, src, dest)
  62.     int robotStream;          /* robot file descriptor */
  63.     int src;                  /* source location */
  64.     int dest;                 /* destination location */
  65. {
  66.     ReturnStatus status;
  67.     Dev_RobotCommand robotCmd;
  68.  
  69.     robotCmd.sourceAddr = src;
  70.     robotCmd.destAddr = dest;
  71.  
  72.     status = Fs_IOControl(robotStream, IOC_ROBOT_MOVE_MEDIUM,
  73.               sizeof(Dev_RobotCommand), &robotCmd, 0, NULL);
  74.  
  75.     if (status != SUCCESS) {
  76.     syserr = Compat_MapCode(status);
  77.     sprintf(printBuf, "Couldn't move robot: status %d, errno %d",
  78.         status, errno);
  79.     Log_Event("Dev_MoveVolume", printBuf, LOG_FAIL);
  80.     return T_FAILURE;
  81.     }
  82.  
  83.     return T_SUCCESS;
  84.  
  85. }
  86.  
  87.  
  88.  
  89. /*
  90.  *----------------------------------------------------------------------
  91.  *
  92.  * Dev_OpenVolume --
  93.  *
  94.  *    Open the device
  95.  *
  96.  * Results:
  97.  *    return code
  98.  *
  99.  * Side effects:
  100.  *    None.
  101.  *
  102.  *----------------------------------------------------------------------
  103.  */
  104.  
  105. int
  106. Dev_OpenVolume(devName, flags)
  107.     char *devName;            /* name of device */
  108.     int flags;                /* read, write etc. flags */
  109. {
  110.     int fd;
  111.  
  112.     if ((fd=open(devName, flags, 0)) == -1) {
  113.     syserr = errno;
  114.     }
  115.     return fd;
  116. }
  117.  
  118.  
  119. /*
  120.  *----------------------------------------------------------------------
  121.  *
  122.  * Dev_CloseVolume --
  123.  *
  124.  *    Close the device
  125.  *
  126.  * Results:
  127.  *    return code
  128.  *
  129.  * Side effects:
  130.  *    None.
  131.  *
  132.  *----------------------------------------------------------------------
  133.  */
  134.  
  135. int
  136. Dev_CloseVolume(stream)
  137.     int stream;               /* file descriptor */
  138. {
  139.     if (close(stream) == -1) {
  140.     syserr = errno;
  141.     return T_FAILURE;
  142.     } else {
  143.     return T_SUCCESS;
  144.     }
  145. }
  146.  
  147.  
  148. /*
  149.  *----------------------------------------------------------------------
  150.  *
  151.  * Dev_ReadVolume --
  152.  *
  153.  *    Perform read operation on volume.
  154.  *
  155.  * Results:
  156.  *    return code
  157.  *
  158.  * Side effects:
  159.  *    None.
  160.  *
  161.  *----------------------------------------------------------------------
  162.  */
  163.  
  164. int
  165. Dev_ReadVolume(volStream, buf, bufSize)
  166.     int volStream;
  167.     char *buf;
  168.     int bufSize;
  169. {
  170.     int cnt;
  171.  
  172.     if ((cnt=read(volStream, buf, bufSize)) < 0) {
  173.     syserr = errno;
  174.     }
  175.     return cnt;
  176. }
  177.  
  178.  
  179. /*
  180.  *----------------------------------------------------------------------
  181.  *
  182.  * Dev_WriteVolume --
  183.  *
  184.  *    Perform write operation on volume.
  185.  *
  186.  * Results:
  187.  *    return code
  188.  *
  189.  * Side effects:
  190.  *    None.
  191.  *
  192.  *----------------------------------------------------------------------
  193.  */
  194.  
  195. int
  196. Dev_WriteVolume(volStream, buf, bufSize)
  197.     int volStream;
  198.     char *buf;
  199.     int bufSize;
  200. {
  201.     int cnt;
  202.  
  203.     if ((cnt=write(volStream, buf, bufSize)) < 0) {
  204.     syserr = errno;
  205.     }
  206.     return cnt;
  207. }
  208.  
  209.  
  210. /*
  211.  *----------------------------------------------------------------------
  212.  *
  213.  * Dev_UnloadVolume --
  214.  *
  215.  *    Open the pod bay door. I'm sorry I can't do that Dave.
  216.  *
  217.  * Results:
  218.  *    return code
  219.  *
  220.  * Side effects:
  221.  *    Rewinds and unloads tape. Moves robot arm.
  222.  *
  223.  *----------------------------------------------------------------------
  224.  */
  225.  
  226. int
  227. Dev_UnloadVolume(devName)
  228.     char *devName;            /* device name */
  229. {
  230.     int volStream;
  231.     Dev_TapeCommand tapeCmd;
  232.     ReturnStatus status;
  233.  
  234.     if ((volStream=open(devName, O_RDONLY, 0)) < 0) {
  235.     syserr = errno;
  236.     return T_FAILURE;
  237.     }
  238.     
  239.     tapeCmd.command = IOC_TAPE_UNLOAD;
  240.     tapeCmd.count = 0;
  241.  
  242.     if ((status=Fs_IOControl(volStream, IOC_TAPE_COMMAND, 
  243.               sizeof(Dev_TapeCommand),
  244.               &tapeCmd, 0, NULL)) != SUCCESS) {
  245.     syserr = Compat_MapCode(status);
  246.         close(volStream);
  247.     return T_FAILURE;
  248.     }
  249.     close(volStream);
  250.  
  251.     return T_SUCCESS;
  252.  
  253. }
  254.  
  255. /*
  256.  *----------------------------------------------------------------------
  257.  *
  258.  * Dev_InitRobot --
  259.  *
  260.  *    Initialize robot.
  261.  *
  262.  * Results:
  263.  *    return code
  264.  *
  265.  * Side effects:
  266.  *    Instructs robot to build database of volume id's
  267.  *      using barcode reader.
  268.  *
  269.  * Note:
  270.  *      At the moment 'initialization' this means taking 
  271.  *      tape inventory.
  272.  *      
  273.  *----------------------------------------------------------------------
  274.  */
  275.  
  276. int
  277. Dev_InitRobot(robotName, robotStreamPtr)
  278.     char *robotName;          /* robot device name */
  279.     int *robotStreamPtr;      /* robot descriptor */
  280. {
  281.     if ((*robotStreamPtr=open(robotName, O_RDONLY, 0)) < 0) {
  282.     syserr = errno;
  283.     return T_FAILURE;
  284.     } else {
  285.     return T_SUCCESS;
  286.     }
  287. }
  288.  
  289.  
  290. /*
  291.  *----------------------------------------------------------------------
  292.  *
  293.  * Dev_ReadVolLabel --
  294.  *
  295.  *    Read volume label with barcode reader
  296.  *
  297.  * Results:
  298.  *    return code
  299.  *
  300.  * Side effects:
  301.  *    Instructs robot to return element status from its database.
  302.  *
  303.  *----------------------------------------------------------------------
  304.  */
  305.  
  306. int
  307. Dev_ReadVolLabel(robotStream, location, volLabel, volIdPtr)
  308.     int robotStream;          /* robot descriptor */
  309.     int location;             /* home slot in jukebox */
  310.     char *volLabel;           /* receiving space for volume label */
  311.     int *volIdPtr;            /* receiving space for converted label */
  312. {
  313.  
  314.     syserr = EINVAL;
  315.     return T_FAILURE;
  316.  
  317. }
  318.  
  319.  
  320. /*
  321.  *----------------------------------------------------------------------
  322.  *
  323.  * Dev_CvtVolLabel --
  324.  *
  325.  *    Convert character volume label to unique integer.
  326.  *
  327.  * Results:
  328.  *    return code
  329.  *
  330.  * Side effects:
  331.  *    None.
  332.  *
  333.  * Note:
  334.  *      For present purposes, labels are of the form "<text><number>"
  335.  *
  336.  *----------------------------------------------------------------------
  337.  */
  338.  
  339. int
  340. Dev_CvtVolLabel(volLabel)
  341.     char *volLabel;
  342. {
  343.     int volId;
  344.     char *workPtr = volLabel+strlen(volLabel)-1;
  345.  
  346.     while ((workPtr >= volLabel) && (isdigit(*workPtr))) {
  347.     workPtr--;
  348.     }
  349.     if ((workPtr >= volLabel) && (sscanf(workPtr+1, "%d", &volId) == 1)) {
  350.     return volId;
  351.     } else {
  352.     return -1;
  353.     }
  354. }
  355.  
  356.  
  357.  
  358.  
  359.  
  360. /*
  361.  *----------------------------------------------------------------------
  362.  *
  363.  * Dev_SeekVolume --
  364.  *
  365.  *    Seek to file marker
  366.  *
  367.  * Results:
  368.  *    return code
  369.  *
  370.  * Side effects:
  371.  *    Instructs tape to seek
  372.  *
  373.  *----------------------------------------------------------------------
  374.  */
  375.  
  376. int
  377. Dev_SeekVolume(volStream, blkId, absolute)
  378.     int volStream;            /* volume descriptor */
  379.     int blkId;                /* logical file num */
  380.     int absolute;             /* absolute positioning flag */
  381. {
  382.     ReturnStatus status;
  383.     Dev_TapeCommand tapeCmd;
  384.     int oldOffset = 0;
  385.     int retryCnt = 0;
  386.  
  387.     if ((blkId < 0) || (blkId > 10000)) {
  388.     fprintf(stderr,"Dev_SeekVolume: Bad blkId: %d\n", blkId);
  389.     }
  390.  
  391.     if ((volStream < 0) || (volStream > 20)) {
  392.     fprintf(stderr,"Dev_SeekVolume: Bad volStream: %d\n", volStream);
  393.     }
  394.  
  395.     if (absolute) {
  396.     status = Ioc_Reposition(volStream, IOC_BASE_ZERO, 0, &oldOffset);
  397.     /* weird spritism. Give it a retry */
  398.     while ((retryCnt++ < 5) && (status != SUCCESS)) {
  399.         fprintf(stderr, "Rewind failed: status 0x%x. Retrying...\n",
  400.             status);
  401.         sleep(2);
  402.         status = Ioc_Reposition(volStream, IOC_BASE_ZERO,
  403.                     0, &oldOffset);
  404.     }
  405.     if (status != SUCCESS) {
  406.         syserr = Compat_MapCode(status);
  407.         fprintf(stderr, "Couldn't rewind tape. status 0x%x\n",status);
  408.         return T_IOFAILED;
  409.     }
  410.     }
  411.  
  412.     if (blkId > 0) {
  413.     tapeCmd.command = IOC_TAPE_SKIP_FILES;
  414.     tapeCmd.count = blkId;
  415.     status = Fs_IOControl(volStream, IOC_TAPE_COMMAND,
  416.                   sizeof(Dev_TapeCommand),
  417.                   (Address)&tapeCmd, 0, (Address) 0);
  418.     if (status != SUCCESS) {
  419.         syserr = Compat_MapCode(status);
  420.         fprintf(stderr, "Couldn't skip %d files: 0x%x\n",
  421.             blkId, status);
  422.         return T_IOFAILED;
  423.     }
  424.     }
  425.  
  426.     return T_SUCCESS;
  427. }
  428.  
  429.  
  430.  
  431. /*
  432.  *----------------------------------------------------------------------
  433.  *
  434.  * Dev_WriteEOF --
  435.  *
  436.  *    write out EOF
  437.  *
  438.  * Results:
  439.  *    return code
  440.  *
  441.  * Side effects:
  442.  *    Puts file marker on tape
  443.  *
  444.  *----------------------------------------------------------------------
  445.  */
  446.  
  447. int
  448. Dev_WriteEOF(volStream, count)
  449.     int volStream;            /* active stream */
  450.     int count;                /* number of marks to write */
  451. {
  452.     ReturnStatus status;
  453.     Dev_TapeCommand tapeCmd;
  454.  
  455.     tapeCmd.command = IOC_TAPE_WEOF;
  456.     tapeCmd.count = count;
  457.  
  458.     status = Fs_IOControl(volStream, IOC_TAPE_COMMAND,
  459.               sizeof(Dev_TapeCommand),
  460.               (Address)&tapeCmd, 0, (Address) 0);
  461.  
  462.     if (status == DEV_RESET) {
  463.     status = Fs_IOControl(volStream, IOC_TAPE_COMMAND,
  464.                   sizeof(Dev_TapeCommand),
  465.                   (Address)&tapeCmd, 0, (Address) 0);
  466.     }
  467.  
  468.     if (status == T_SUCCESS) {
  469.     return T_SUCCESS;
  470.     } else {
  471.     syserr = Compat_MapCode(status);
  472.     return T_IOFAILED;
  473.     }
  474. }
  475.  
  476.  
  477.  
  478. /*
  479.  *----------------------------------------------------------------------
  480.  *
  481.  * Dev_GetVolStatus --
  482.  *
  483.  *    Inquire into state of volume device
  484.  *
  485.  * Results:
  486.  *    return code
  487.  *
  488.  * Side effects:
  489.  *    None.
  490.  *
  491.  *----------------------------------------------------------------------
  492.  */
  493.  
  494. int
  495. Dev_GetVolStatus(volStream, volStatusPtr)
  496.     int volStream;            /* volume descriptor */
  497.     VolStatus *volStatusPtr;  /* receiving structure */
  498. {
  499.     ReturnStatus status;
  500.     Dev_TapeStatus tapeStatus;
  501.  
  502.     status = Fs_IOControl(volStream, IOC_TAPE_STATUS, 0, NULL,
  503.               sizeof(Dev_TapeStatus), (Address)&tapeStatus);
  504.  
  505.     if (status == DEV_RESET) {
  506.     status = Fs_IOControl(volStream, IOC_TAPE_STATUS, 0, NULL,
  507.                   sizeof(Dev_TapeStatus),
  508.                   (Address)&tapeStatus);
  509.     }
  510.     if (status == SUCCESS) {
  511.     volStatusPtr->speed = tapeStatus.speed;
  512.     volStatusPtr->density = tapeStatus.density;
  513.     volStatusPtr->remaining = tapeStatus.remaining;
  514.     volStatusPtr->position = tapeStatus.position;
  515.     volStatusPtr->writeProtect = tapeStatus.writeProtect;
  516.     return T_SUCCESS;
  517.     } else {
  518.     syserr = Compat_MapCode(status);
  519.     return T_IOFAILED;
  520.     }
  521.  
  522. }
  523.  
  524. /*
  525.  *----------------------------------------------------------------------
  526.  *
  527.  * Dev_DisplayMsg --
  528.  *
  529.  *    Display message on jukebox screen
  530.  *
  531.  * Results:
  532.  *    return code
  533.  *
  534.  * Side effects:
  535.  *    Changes display on robot front panel.
  536.  *
  537.  *----------------------------------------------------------------------
  538.  */
  539.  
  540. int
  541. Dev_DisplayMsg(robotStream, msg, msgStyle)
  542.     int robotStream;          /* volume descriptor */
  543.     char *msg;                /* Message text */
  544.     int msgStyle;             /* 0==Steady, 1==flash, 2==scroll */
  545. {
  546.     ReturnStatus status;
  547.     Dev_RobotCommand robotCmd;
  548.     
  549.     robotCmd.savedPage = 1;
  550.     robotCmd.mesgDisplay = msgStyle;
  551.     robotCmd.mesgString = msg;
  552.     status = Fs_IOControl(robotStream, IOC_ROBOT_DISPLAY,
  553.               sizeof(Dev_RobotCommand),
  554.               &robotCmd, 0, NULL);
  555.  
  556.     if (status != SUCCESS) {
  557.     syserr = Compat_MapCode(status);
  558.     fprintf(printBuf, "Couldn't set display: status %d, errno %d",
  559.         status, syserr);
  560.     return T_FAILURE;
  561.     } else {
  562.          return T_SUCCESS;
  563.     }
  564. }
  565.  
  566.  
  567. /*
  568.  *----------------------------------------------------------------------
  569.  *
  570.  * Dev_OpenDoor --
  571.  *
  572.  *    Open (or at least unlock) the jukebox door.
  573.  *
  574.  * Results:
  575.  *    return code
  576.  *
  577.  * Side effects:
  578.  *    None.
  579.  *
  580.  *----------------------------------------------------------------------
  581.  */
  582.  
  583. int
  584. Dev_OpenDoor(robotStream)
  585.     int robotStream;          /* robot descriptor */
  586.     return T_SUCCESS;
  587. }
  588.  
  589.  
  590. /*
  591.  *----------------------------------------------------------------------
  592.  *
  593.  * Dev_RemoveVolume --
  594.  *
  595.  *    Open (or at least unlock) the jukebox door.
  596.  *
  597.  * Results:
  598.  *    return code
  599.  *
  600.  * Side effects:
  601.  *    Kicks a volume out of archive.
  602.  *
  603.  *----------------------------------------------------------------------
  604.  */
  605.  
  606. int
  607. Dev_RemoveVolume(robotStream, src)
  608.     int robotStream;          /* robot descriptor */
  609.     int src;                  /* src slot location */
  610.     ReturnStatus status;
  611.     Dev_RobotCommand robotCmd;
  612.  
  613.     robotCmd.sourceAddr = src;
  614.     robotCmd.destAddr = 120; /* slot id of entry/exit port */
  615.     robotCmd.eePos = 0x40;   /* spit volume out to user */
  616.  
  617.     status = Fs_IOControl(robotStream, IOC_ROBOT_MOVE_MEDIUM,
  618.               sizeof(Dev_RobotCommand), &robotCmd, 0, NULL);
  619.  
  620.     if (status != SUCCESS) {
  621.     syserr = Compat_MapCode(status);
  622.     sprintf(printBuf, "Couldn't remove volume: status %d, errno %d",
  623.         status, errno);
  624.     Log_Event("Dev_RemoveVolume", printBuf, LOG_FAIL);
  625.     return T_FAILURE;
  626.     }
  627.  
  628.     return T_SUCCESS;
  629.  
  630. }
  631.  
  632.  
  633. /*
  634.  *----------------------------------------------------------------------
  635.  *
  636.  * Dev_InsertVolume --
  637.  *
  638.  *    Open (or at least unlock) the jukebox door.
  639.  *
  640.  * Results:
  641.  *    return code
  642.  *
  643.  * Side effects:
  644.  *    Pull in a new volume.
  645.  *
  646.  *----------------------------------------------------------------------
  647.  */
  648.  
  649. int
  650. Dev_InsertVolume(robotStream, dest)
  651.     int robotStream;          /* robot descriptor */
  652.     int dest;                 /* destination slot location */
  653.     ReturnStatus status;
  654.     Dev_RobotCommand robotCmd;
  655.  
  656.     robotCmd.sourceAddr = 120; /* slot id of entry/exit port */
  657.     robotCmd.destAddr = dest;
  658.     robotCmd.eePos = 0x80;     /* suck volume in from user */
  659.  
  660.     status = Fs_IOControl(robotStream, IOC_ROBOT_MOVE_MEDIUM,
  661.               sizeof(Dev_RobotCommand), &robotCmd, 0, NULL);
  662.  
  663.     if (status != SUCCESS) {
  664.     syserr = Compat_MapCode(status);
  665.     sprintf(printBuf, "Couldn't insert volume: status %d, errno %d",
  666.         status, errno);
  667.     Log_Event("Dev_InsertVolume", printBuf, LOG_FAIL);
  668.     return T_FAILURE;
  669.     }
  670.  
  671.     return T_SUCCESS;
  672.  
  673. }
  674.  
  675. /*
  676.  *----------------------------------------------------------------------
  677.  *
  678.  * Dev_BuildVolList --
  679.  *
  680.  *    Build a list of jukebox's contents
  681.  *
  682.  * Results:
  683.  *    return code
  684.  *
  685.  * Side effects:
  686.  *    none.
  687.  *
  688.  *----------------------------------------------------------------------
  689.  */
  690.  
  691. int
  692. Dev_BuildVolList(robotStream, listPtr, cntPtr)
  693.     int robotStream;          /* robot descriptor */
  694.     VolConfig *listPtr;       /* space for volume info */
  695.     int *cntPtr;              /* size of list */
  696.                 
  697.     int i;
  698.     int cnt = 0;
  699.     int maxBin = EXB120_MAXBIN+1;
  700.     int retCode = T_SUCCESS;
  701.     char label[T_MAXLABELLEN];
  702.     
  703.     if (*cntPtr < maxBin) {
  704.     syserr = ENOSPC;
  705.     *cntPtr = EXB120_MAXBIN+1;
  706.     return T_FAILURE;
  707.     }
  708.  
  709.     for (i=0; i<maxBin; i++) {
  710.     if ((retCode=Dev_ReadVolLabel(robotStream, i, label)) != T_SUCCESS) {
  711.         *cntPtr = 0;
  712.         return retCode;
  713.     }
  714.     listPtr->volId = i;
  715.     listPtr->location = i;
  716.     strcpy(listPtr->volLabel, label);
  717.     listPtr++;
  718.     cnt++;
  719.     }
  720.  
  721.     *cntPtr = cnt;
  722.     return T_SUCCESS;
  723.  
  724. }
  725.